package com.dk.controller;

import com.alibaba.fastjson.JSONObject;
import com.dk.data.Result;
import com.dk.dto.UsersDto;
import com.dk.em.ResultEnum;
import com.dk.entity.DtUser;
import com.dk.entity.Users;
import com.dk.mapper.DtUserMapper;
import com.dk.util.JwtUtil;
import com.dk.util.ShiroUtils;
import com.netflix.zuul.context.RequestContext;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.QuerySendDetailsRequest;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.aliyun.tea.*;
import com.aliyun.dysmsapi20170525.*;
import com.aliyun.dysmsapi20170525.models.*;
import com.aliyun.teaopenapi.*;
import com.aliyun.teaopenapi.models.*;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("login")
@Api(value = "shiro整合登录注册")
public class LoginController {




    @GetMapping
    public String login(){

        return "go";
    }

    @Autowired RedisTemplate redisTemplate;

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    DtUserMapper dtUserMapper;

    @PostMapping
    @ApiOperation(value = "用户的登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "登录用户名", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "用户密码", required = true, paramType = "query")
    })
    //paramType : body : 表示@RequestBody接收的实体类 path : 表示路径/{}传参 query:表示@ RequestParam接收参数
    public Result login(@RequestParam("userName") String userName, @RequestParam("password") String password){
         /*
        登录态获取http要放在参数里
        HttpServletRequest request
        request.getHeader();*/
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName,password);
        try{
            subject.login(token);
        }catch (UnknownAccountException e1){
            //账号不存在
            return Result.response(ResultEnum.GATEWAY_FALLBACK);
        }catch (IncorrectCredentialsException e2){
            //密码错误
            return Result.response(ResultEnum.GATEWAY_FALLBACK);
        }
        //整合shiro
        //1.创建subject2.封装sername，password对象
        //3.调用subject的login方法4.try catch 登陆成功后返回成功页面
        //5.将登陆用户取出登陆成功之后 subject.get()
        //先new一个练习
        Users user = new Users();
        user.setId(1).setUserName(userName).setPassword(password).setNickName("吴彦祖");
        //将user对象脱敏处理
        UsersDto dto = new UsersDto();
        BeanUtils.copyProperties(user,dto);
        //1.  token+redis
       /* //生产token令牌
        String token = UUID.randomUUID().toString();

        redisTemplate.boundValueOps(token).set(dto);
        //设置有效时间30分钟
        redisTemplate.expire(token,30, TimeUnit.MINUTES);*/

        //2.  JWT
        String token1 = jwtUtil.createJwt(dto.getId().toString(), JSONObject.toJSONString(dto), "guest"); //如果后台用的带角色就写相应角色，不带的话就给默认统一的
        return Result.response(ResultEnum.SUCCESS).setData(token1);
    }

    @PutMapping
    @ApiOperation(value = "用户的注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "登录用户名", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "用户密码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "email", value = "用户邮箱", required = true, paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "用户手机号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query")
    })
    public Result addRegister(@RequestParam("userName") String userName, @RequestParam("password") String password, @RequestParam("email") String email, @RequestParam("phone") String phone, @RequestParam("code") String code){
        //加密加盐
        //获取撒盐的长度
        //System.out.println(code);
        String code1 = (String) redisTemplate.boundValueOps(phone).get();
        if (!code1.equals(code)) {
            return Result.response(ResultEnum.ARGS_ERROR);
        }

        //String s = "67e076";
        String s = ShiroUtils.generateSalt(6);
        String md5 = ShiroUtils.encryptPassword("MD5", password, s, 3);
        //存密码
        DtUser dtUser = new DtUser();
        dtUser.setUsername(userName);
        dtUser.setPassword(md5);
        dtUser.setSalt(s);
        dtUser.setCreated(new Date());
        dtUser.setUpdated(new Date());
        dtUser.setEmail(email);
        dtUser.setPhone(phone);



//        tbSeller.setPassword(md5);
//        tbSeller.setSalt(s);
//        tbSeller.setCreated(new Date());
//        tbSeller.setUpdated(new Date());
        //存盐没字段不存写死"67e076"
        try {
            //int i = userService.addSeller(tbSeller);
            int i = dtUserMapper.insert(dtUser);
            return Result.response(ResultEnum.SUCCESS).setData(i);
        }catch (Exception e){
            return Result.response(ResultEnum.ERROR).setData(e);
        }

    }
    @PostMapping("phone")
    @ApiOperation(value = "用户注册发送信息")
    @ApiImplicitParam(name = "phoneNum", value = "注册的手机号", required = true, paramType = "query")
    public void sendPhoneMessage(String phoneNum) {
        // java.util.List<String> args = java.util.Arrays.asList(args_);
        Client client = null;
        try {
            client = createClient("LTAI4GCbdwnjCGwQj9Z3tr3N", "27ih4pc1W1tqey9X4mmCy1JUotAX7L");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String code = RandomStringUtils.randomNumeric(4);
        redisTemplate.boundValueOps(phoneNum).set(code);
        redisTemplate.expire(phoneNum,30, TimeUnit.MINUTES);
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(phoneNum);
        sendSmsRequest.setSignName("东科创想");//签名名字
        sendSmsRequest.setTemplateCode("SMS_162522027");//模板名字
        sendSmsRequest.setTemplateParam("{\"sms_code\":\"" + code + "\"}");//模板需要的变量
        // 复制代码运行请自行打印 API 的返回值
        try {
            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
            SendSmsResponseBody body = sendSmsResponse.getBody();
            System.out.println("返回码" + body.getCode());
            System.out.println("返回信息" + body.getMessage());
            String code1 = body.getCode();
            //redisTemplate.boundValueOps(phoneNum).set(code1,1800, TimeUnit.SECONDS);
            body.getMessage();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }
}
